/* eslint-disable @typescript-eslint/naming-convention */
import { environment } from 'src/environments/environment';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { tap, mapTo, catchError } from 'rxjs/operators';
import { AlertController } from '@ionic/angular';
import { Router } from '@angular/router';
import { StorageService } from './storage.service';
import { Constant } from '../model/constants';

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  constructor(
    private http: HttpClient,
    private alertCtrl: AlertController,
    private router: Router,
    private storageService: StorageService
  ) {}

  public get loggedUser() {
    return this.storageService.get(Constant.User_Name);
  }

  public login(user: { email: string; password: string }): Observable<boolean> {
    return this.http.post<any>(`${environment.baseUrl}/account/login`, user).pipe(
      tap((tokens) => {
        this.doLoginUser(user.email, tokens);
      }),
      mapTo(true),
      catchError((error) => {
        this.alertCtrl
          .create({
            header: '',
            subHeader: '邮箱地址或者密码错误！',
            message: '',
            buttons: ['确定'],
          })
          .then((n) => n.present());
        throw error;
      })
    );
  }

  public logout() {
    return this.http
      .post<any>(`${environment.baseUrl}/account/logout`, {
        refreshToken: this.getRefreshToken(),
        accessToken: this.getAccessToken(),
      })
      .pipe(
        tap(() => this.doLogoutUser()),
        mapTo(true),
        catchError((error) => {
          console.log(error);
          return of(false);
        })
      );
  }

  public isLoggedIn() {
    return !!this.getAccessToken();
  }
  public getAccessToken() {
    return this.storageService.get(Constant.Access_Token);
  }
  public refreshTokens() {
    return this.http
      .post<any>(`${environment.baseUrl}/account/refreshToken`, {
        refreshToken: this.getRefreshToken(),
        accessToken: this.getAccessToken(),
      })
      .pipe(
        tap((tokens: Tokens) => {
          this.storeTokens(tokens);
        })
      );
  }

  private doLoginUser(username: string, tokens: Tokens) {
    this.storeTokens(tokens);
  }

  private doLogoutUser() {
    this.removeTokens();
    this.router.navigate(['/tabs/profile']).then();
  }

  private getRefreshToken() {
    return this.storageService.get(Constant.Refresh_Token);
  }

  private storeTokens(tokens: Tokens) {
    this.storageService.set(Constant.Access_Token, tokens.accessToken);
    this.storageService.set(Constant.Refresh_Token, tokens.refreshToken);
  }
  private removeTokens() {
    this.storageService.remove(Constant.Access_Token);
    this.storageService.remove(Constant.Refresh_Token);
  }
}
export interface Tokens {
  refreshToken: string;
  accessToken: string;
}
